
#include "module.h"
#include "luac.h"
#include "luas.h"
 


int mod_new()
{
    Module *mod = (Module *)malloc(sizeof(Module));
    bzero(mod, sizeof(Module));
    return mod2fd(mod);
}
int mod_mgr_load_modules(const char *dirpath)
{
    js_sys("module", "load modules from dirpath:%s\n", dirpath);
    DIR *dir = opendir(dirpath);
    struct dirent *dp;
    while(dp = readdir(dir))
    {
        const char *modname = dp->d_name;
        if(modname[0] == '.')continue;
        if(!strcmp(modname, "."))continue;
        if(!strcmp(modname, ".."))continue;
        
        js_sys("module", "===============module %s============\n", modname);
        mod_mgr_load_module(dirpath, modname);
        js_sys("module", "===============module %s============\n\n", modname);
    }
    return 1; 
}

int mod_mgr_load_module(const char *dirpath, const char *modname)
{
    char lua_file_path[128];
    char func_init[128];
    

    int modfd = mod_new();
    Module* mod = fd2mod(modfd);
    sprintf(mod->mod_dir, "%s/%s", dirpath, modname);
    DIR *dir = opendir(mod->mod_dir);
    struct dirent *dp;
    while(dp = readdir(dir))
    {
        const char *filename = dp->d_name;
        sprintf(lua_file_path, "%s/%s", mod->mod_dir, filename);
        if(!strstr(filename, ".lua"))continue;
        
        js_sys("module", "load lua %s...\n", filename);
        luas_dofile(lua_file_path);
    }
    sprintf(func_init, "%s_init", modname);
    
    luas_callfunc(func_init, "()");
    
    mod->next_mod = LUAC.mod_list;
    LUAC.mod_list = mod;
    return 1;
}
static void on_lua_timer(const int fd, const short which, void *arg)
{    
    Handler *handler = (Handler *)arg;
    Handler_LUA_Timer *hand_data = (Handler_LUA_Timer*)handler->hand_data;
    
    js_sys("module", "on_lua_timer %s\n", hand_data->callback);

    int ir = luas_callfunc(hand_data->callback, "(%d)",
        handler2msgid(handler));
    if(ir == 1)
    { 
        evtimer_add(&(hand_data->evt), &(hand_data->tv));
    }
}
int mod_mgr_dispatch(int linefd, int msgid, int pktfd)
{
    
    Handler *handler = dictFetchValue(LUAC.msg_map, (void*)msgid);
    if(!handler)
    { 
        js_sys("module", "mod_mgr_dispatch can't find handler for msg:%d\n", msgid);
        return;
    }
    js_sys("module", "mod_mgr_dispatch linefd:%d msgid:%d hand_type:%d\n", linefd, msgid, handler->hand_type);
    switch(handler->hand_type)
    {
        case HANDLER_LUA_MSG: 
        {
            Handler_LUA_Msg *hand_data = (Handler_LUA_Msg*)handler->hand_data;
            int ir = luas_callfunc(hand_data->callback, "(%d, %d)",
                linefd,
                msgid
                );
        }        
        break;
        default:
        {
            js_sys("module", "mod_mgr_dispatch unknown handler type %d\n", handler->hand_type);
        }break;
    }
}
int mod_mgr_insert_lua_timer(int msgid, int msec, const char* funcname)
{
    Handler *handler = (Handler *)malloc(sizeof(Handler)+sizeof(Handler_LUA_Timer));

    handler->hand_type = HANDLER_LUA_TIMER;    
    
    handler->msgid = msgid;    
    Handler_LUA_Timer *hand_data = (Handler_LUA_Timer*)handler->hand_data;
    
    int sec = msec / 1000;
    int usec = (msec % 1000) * 1000;
    
    hand_data->tv.tv_sec  = sec;
    hand_data->tv.tv_usec = usec;
    strcpy(hand_data->callback, funcname);
    
    evtimer_set(&(hand_data->evt), on_lua_timer, handler);
    evtimer_add(&(hand_data->evt), &(hand_data->tv));
    js_sys("module", "mod_mgr_insert_lua_timer msgid:%d funcname:%s\n", msgid,  funcname);
    
    return 1;
}

int mod_mgr_insert_lua_func(int msgid, const char* funcname)
{
    js_sys("module", "mod_mgr_insert_lua_func  msgid:%d funcname:%s\n", msgid,  funcname);
    Handler *handler = (Handler *)malloc(sizeof(Handler)+sizeof(Handler_LUA_Msg));
    handler->hand_type = HANDLER_LUA_MSG;       
    handler->msgid = msgid;     
    
    Handler_LUA_Msg *hand_data = (Handler_LUA_Msg*)handler->hand_data;
    strcpy(hand_data->callback, funcname);
    


    dictReplace(LUAC.msg_map, (void*)msgid, (void*)handler);

    return 1;
}

static luaL_Reg lua_lib[] = 
{
    {NULL, NULL}
};

int mod_init()
{
	luas_reg_lib("ModMgr", lua_lib);
}

